GuardDutyとその結果をFirehose経由でDatadogに連携するCloudFormationテンプレートを作ってみた
AWS チームのすずきです。
HTTPエンドポイントに対応した Kinesis Data Firehose を利用して、 Guradduty の 検出結果をを、Datadog Log に連携して利用する方法について紹介させて頂きました。
今回、Guradduty、EventBrige、Firehose を StackSetを利用して一括設定できる CloudFormation テンプレート を用意する機会がありましたので、紹介させていただきます。
CloudFormation
Firehose
- 「HttpEndpointDestinationConfiguration」以下でHTTPエンドポイント設定を行います。
-
Datadog 指定のURLと APIキーを「EndpointConfiguration」以下に反映します。
FirehoseStream: Type: AWS::KinesisFirehose::DeliveryStream Properties: HttpEndpointDestinationConfiguration: EndpointConfiguration: AccessKey: !Ref 'DatadogAccessKey' Url: https://aws-kinesis-http-intake.logs.datadoghq.com/v1/input Name: Datadog BufferingHints: SizeInMBs: 4 IntervalInSeconds: 60 CloudWatchLoggingOptions: Enabled: true LogGroupName: !Sub '/aws/kinesisfirehose/${AWS::StackName}' LogStreamName: HttpEndpointDelivery RequestConfiguration: ContentEncoding: GZIP RoleARN: !GetAtt 'FirehoseStreamRole.Arn' RetryOptions: DurationInSeconds: 60 S3BackupMode: AllData S3Configuration: RoleARN: !GetAtt 'FirehoseStreamRole.Arn' BucketARN: !Sub 'arn:aws:s3:::${S3BucketFirehose}' Prefix: !Sub '${AWS::StackName}-backup/' ErrorOutputPrefix: !Sub '${AWS::StackName}-error/' BufferingHints: SizeInMBs: 10 IntervalInSeconds: 600 CompressionFormat: GZIP CloudWatchLoggingOptions: Enabled: true LogGroupName: !Sub '/aws/kinesisfirehose/${AWS::StackName}' LogStreamName: S3Delivery
EventBridge
- GuardDuty により検出されたイベントを Firehoseに転送します。
EventsRuleGuardDutyFinding: Type: AWS::Events::Rule Properties: Description: EventRule EventPattern: source: - aws.guardduty detail-type: - GuardDuty Finding State: ENABLED Targets: - Arn: !GetAtt 'FirehoseStream.Arn' Id: EventsRuleGuardDutyFinding RoleArn: !GetAtt 'EventBridgeRole.Arn'
- 重要度の高い GuardDuty検出結果(severity:[5,8])のみ、処理対象とするフィルタも可能です。
EventPattern: source: - aws.guardduty detail-type: - GuardDuty Finding detail: severity: - 8 - 5
IAM
EventBridge と Firehose 用のIAMロールを用意しました。
EventBridgeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: firehose-putrecord PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - firehose:PutRecord - firehose:PutRecords Resource: !GetAtt 'FirehoseStream.Arn' FirehoseStreamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Sid: '' Effect: Allow Principal: Service: firehose.amazonaws.com Action: sts:AssumeRole Condition: StringEquals: sts:ExternalId: !Ref 'AWS::AccountId' FirehoseStreamPolicy: Type: AWS::IAM::Policy Properties: PolicyName: firehose_delivery_policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:PutLogEvents Resource: - !Sub '${LogGroupFirehose.Arn}:log-stream:*' - Effect: Allow Action: - s3:AbortMultipartUpload - s3:GetBucketLocation - s3:GetObject - s3:ListBucket - s3:ListBucketMultipartUploads - s3:PutObject Resource: - !Sub 'arn:aws:s3:::${S3BucketFirehose}' - !Sub 'arn:aws:s3:::${S3BucketFirehose}/*' Roles: - !Ref 'FirehoseStreamRole'
CloudWatch logs
Firehose ログ書き込み用の設定を用意します。
CloudFormation でロググループを設置する事で、CloudWatchLogsに登録されたログが残り続ける事を回避します。
LogGroupFirehose: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub '/aws/firehose/${AWS::StackName}' RetentionInDays: 7 LogStreamS3Delivery: Type: AWS::Logs::LogStream Properties: LogGroupName: !Ref 'LogGroupFirehose' LogStreamName: S3Delivery LogStreamHttpEndpointDelivery: Type: AWS::Logs::LogStream Properties: LogGroupName: !Ref 'LogGroupFirehose' LogStreamName: HttpEndpointDelivery
S3
Firehose の出力先となるS3バケットを設置します。
S3のストレージ費用を抑制するため、S3のライフサイクル設定を実施、パブリックアクセスは禁止としています。
S3BucketFirehose: Type: AWS::S3::Bucket Properties: LifecycleConfiguration: Rules: - Id: AutoDelete Status: Enabled ExpirationInDays: 14 - Id: NoncurrentVersionExpiration Status: Enabled NoncurrentVersionExpirationInDays: 7 - Id: AbortIncompleteMultipartUpload Status: Enabled AbortIncompleteMultipartUpload: DaysAfterInitiation: 7 PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true VersioningConfiguration: Status: Enabled
テンプレートリンク
今回のテンプレート、全文は以下で公開中です。
StackSet
StackSetsによる全リージョン一括有効化 の手順で、任意のリージョンに一括展開する事が可能です。
Firehoseによるデータ圧縮や、S3のライフサイクル設定により、S3のコストは抑制した利用が期待できますが、 S3バケットの設置数は、1つのAWSアカウントあたり100個の制限が存在します。
今回のテンプレートでは、Firehose のバックアップ先となるS3バケットが各リージョンに設置されます。
多数のS3バケットを設置済みの環境では、事前にサービスクォータを利用した上限緩和を実施してご利用ください。
まとめ
今回紹介したCloudFormationテンプレート、以下ブログで紹介されている、SNS / Lambda を Kinesis Data Firehose で置き換えた内容となります。
Firehose は 簡単な設定で 安定したデータ転送を実現する事が可能です。 連携先が Firehose との連携をサポートする場合、Firehose をぜひお試しください。